2.5.2 Fetch API

La Fetch API permite realizar solicitudes de red (HTTP) para obtener, enviar, actualizar o eliminar datos de un servidor de manera asíncrona, usando fetch(). Su sintaxis básica es sencilla y se basa en el uso de promesas, lo que facilita el manejo de respuestas y errores.

Sintaxis Básica

fetch(url, options)
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));

Ejemplo con Fake Store API: Obtener productos

Vamos a hacer una solicitud para obtener la lista de productos de Fake Store API y mostrar los datos en la consola.

fetch('https://fakestoreapi.com/products')
    .then(response => {
        if (!response.ok) {
            throw new Error('Error en la solicitud');
        }
        return response.json(); // Convertir la respuesta en JSON
    })
    .then(data => {
        console.log('Lista de productos:', data); // Procesar los datos
    })
    .catch(error => {
        console.error('Error:', error); // Manejo de errores
    });

Métodos de Solicitud con la Fetch API

Además de GET, la Fetch API permite otros métodos de solicitud para crear, actualizar y eliminar datos.

1. POST - Crear un nuevo producto

Con POST, podemos enviar datos al servidor. Vamos a simular la creación de un producto en la API.

fetch('https://fakestoreapi.com/products', {
    method: 'POST', // Definimos el método POST
    headers: {
        'Content-Type': 'application/json' // Indicamos el tipo de contenido
    },
    body: JSON.stringify({
        title: 'Nuevo Producto',
        price: 19.99,
        description: 'Descripción del producto',
        image: 'https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg',
        category: 'electrónica'
    })
})
.then(response => {
    if (!response.ok) {
        throw new Error('Error al crear el producto');
    }
    return response.json();
})
.then(data => {
    console.log('Producto creado:', data);
})
.catch(error => {
    console.error('Error:', error);
});

2. PUT - Actualizar un producto existente

El método PUT se usa para actualizar datos en el servidor. Supongamos que queremos actualizar el producto con id = 1.

fetch('https://fakestoreapi.com/products/1', {
    method: 'PUT', // Método PUT para actualizar
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        title: 'Producto Actualizado',
        price: 29.99,
        description: 'Descripción actualizada',
        image: 'https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg',
        category: 'electrónica'
    })
})
.then(response => {
    if (!response.ok) {
        throw new Error('Error al actualizar el producto');
    }
    return response.json();
})
.then(data => {
    console.log('Producto actualizado:', data);
})
.catch(error => {
    console.error('Error:', error);
});

3. DELETE - Eliminar un producto

Con DELETE, podemos eliminar un recurso específico en el servidor. Supongamos que queremos eliminar el producto con id = 1.

fetch('https://fakestoreapi.com/products/1', {
    method: 'DELETE' // Método DELETE para eliminar el recurso
})
.then(response => {
    if (!response.ok) {
        throw new Error('Error al eliminar el producto');
    }
    return response.json();
})
.then(data => {
    console.log('Producto eliminado:', data);
})
.catch(error => {
    console.error('Error:', error);
});

Resumen de los Métodos de Solicitud con Fetch API

Método Descripción Ejemplo
GET Obtiene datos del servidor Obtener lista de productos
POST Envía nuevos datos al servidor Crear un nuevo producto
PUT Actualiza datos existentes en el servidor Actualizar un producto existente
DELETE Elimina un recurso específico del servidor Eliminar un producto específico

Ejercicio Fake News

Crear un componente Web <news-viewer> que:

  1. Obtenga los artículos desde la API al cargarse.
  2. Use una plantilla HTML para mostrar cada artículo con el título, autor y descripción.
  3. Usar el endpoint: https://fakenews.squirro.com

Estructura del HTML

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Visor de Noticias Falsas</title>
</head>
<body>

  <h1>Artículos de Noticias Falsas</h1>
  <!-- Componente personalizado -->
  <news-viewer></news-viewer>

  <!-- Plantilla para un artículo -->
  <template id="article-template">
    <div class="article">
      <h3 class="title"></h3>
      <p><strong>Autor:</strong> <span class="author"></span></p>
      <p class="description"></p>
      <hr>
    </div>
  </template>

  <script src="news-viewer.js"></script>

</body>
</html>

JavaScript: news-viewer.js

Este archivo JavaScript define el componente NewsViewer, que obtiene los artículos y los renderiza usando la plantilla HTML.


class NewsViewer extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    this.loadArticles();
  }

  async loadArticles() {
    try {
      const response = await fetch('https://news-foniuhqsba-uc.a.run.app');
      if (!response.ok) {
        throw new Error('Error al obtener los artículos');
      }
      const articles = await response.json();
      this.renderArticles(articles);
    } catch (error) {
      console.error('Error:', error);
      this.innerHTML = `<p>Error al cargar los artículos. Inténtelo nuevamente más tarde.</p>`;
    }
  }

  renderArticles(articles) {
    const template = document.getElementById('article-template');
    
    // Limpiar contenido existente
    this.innerHTML = '';

    articles.forEach(article => {
      // Clonar el contenido de la plantilla
      const articleContent = document.importNode(template.content, true);
      
      // Rellenar la plantilla con los datos del artículo
      articleContent.querySelector('.title').textContent = article.headline;
      articleContent.querySelector('.author').textContent = article.author;
      articleContent.querySelector('.description').innerHTML = article.body;
      
      // Añadir el artículo al componente
      this.appendChild(articleContent);
    });
  }
}

// Definir el elemento personalizado
customElements.define('news-viewer', NewsViewer);